package javase.reflect;

import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Java反射解析XML字符串并封装到指定的JavaBean
 * User: Realfighter
 * Date: 2014/10/30
 * Time: 12:43
 */
public class XmlUtils {

    private String firstXmlStr;//测试xml
    private String secondXmlStr;//测试xml

    @Before
    public void setUp() throws Exception {
        //这里随便在网上搜索的xml字符串，简单做了修改
        firstXmlStr = "<?xml version=\"1.0\" encoding=\"GBK\"?>" +
                "<Result xmlns=\"http://www.xx566.com\">" +
                    "<row resultcount=\"1\">" +
                        "<users_id>1001     </users_id>" +
                        "<users_name>Realfighter   </users_name>" +
                        "<users_group>81        </users_group>" +
                        "<users_address>1001号   </users_address>" +
                    "</row>" +
                "</Result>";
        secondXmlStr = "<?xml version=\"1.0\" encoding=\"GBK\"?>" +
                "<Result xmlns=\"http://www.xx566.com\">" +
                    "<row resultcount=\"1\">" +
                        "<users_id>1001     </users_id>" +
                        "<users_name>Realfighter   </users_name>" +
                        "<users_group>81        </users_group>" +
                        "<users_address>1001号   </users_address>" +
                    "</row>" +
                    "<row resultcount=\"2\">" +
                        "<users_id>1002     </users_id>" +
                        "<users_name>Realfighter2   </users_name>" +
                        "<users_group>82        </users_group>" +
                        "<users_address>1002号   </users_address>" +
                    "</row>" +
                "</Result>";
    }

    @Test
    public void testFirstXmlStr() {
        User user = (User) packReturnByXml(firstXmlStr, new User());
        System.out.println(user.toString());
        //执行结果：
        //User{users_id=1001, users_name='Realfighter', users_group=81, users_address='1001号'}
    }

    /**
     * 封装xml信息到指定的Object
     *
     * @param returnXml
     * @param obj
     * @return Object
     * @throws
     * @Title: packReturnByXml
     * @author Realfighter
     */
    public static Object packReturnByXml(String returnXml, Object obj) {
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String fieldname = field.getName();
            try {
                Pattern p = Pattern.compile("<" + fieldname + ">.*?</"
                        + fieldname + ">");
                //匹配类似：<users_id>1001     </users_id>的字符
                Matcher matcher = p.matcher(returnXml);
                while (matcher.find()) {
                    Pattern p1 = Pattern.compile(">([^<>]*)<");
                    //匹配类似：>1001     <的字符
                    Matcher m1 = p1.matcher(matcher.group(0).trim());
                    if (m1.find()) {
                        String value = m1.group(1).trim().equals("") ? null
                                : m1.group(1).trim();
                        Class<?> beanType = field.getType();
                        String setMethodName = "set"
                                + fieldname.substring(0, 1).toUpperCase()
                                + fieldname.substring(1);
                        Method m = obj.getClass().getMethod(setMethodName,
                                beanType);
                        m.invoke(obj, value);
                    }
                }
            } catch (Exception e) {
                continue;
            }
        }
        return obj;
    }

    @Test
    public void testSecondXmlStr() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        BaseObject[] objs = packReturnArrayByXml(secondXmlStr, new User());
        for (BaseObject base : objs) {
            System.out.println(((User) base).toString());
        }
        //执行结果：
        //User{users_id=1001, users_name='Realfighter', users_group=81, users_address='1001号'}
        //User{users_id=1002, users_name='Realfighter2', users_group=82, users_address='1002号'}
    }

    /**
     * 解析xml,封装成returnbean数组
     *
     * @param returnXml
     * @param obj
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public static BaseObject[] packReturnArrayByXml(String returnXml, BaseObject obj)
            throws IllegalArgumentException, IllegalAccessException,
            SecurityException, NoSuchMethodException, InvocationTargetException {

        Field[] fields = obj.getClass().getDeclaredFields();

        List<Object> objs = new ArrayList<Object>();

        int count = 0;//临时变量，用于计算可匹配到的对象数目

        for (Field field : fields) {
            field.setAccessible(true);
            String fieldname = field.getName();
            Pattern p = Pattern.compile("<" + fieldname + ">.*?</"
                    + fieldname + ">");
            Matcher matcher = p.matcher(returnXml);
            while (matcher.find()) {
                //对象的复制方法
                Object _obj = obj.clone();
                objs.add(_obj);
                count++;
            }
            if (count > 0) {
                //一旦获取到对象数组，结束循环
                break;
            }
        }
        BaseObject[] objs2 = new BaseObject[count];
        for (int i = 0; i < count; i++) {
            Object obj1 = objs.get(i);
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldname = field.getName();
                try {
                    Pattern p = Pattern.compile("<" + fieldname + ">.*?</"
                            + fieldname + ">");
                    Matcher matcher = p.matcher(returnXml);
                    int num = 0;
                    while (matcher.find()) {
                        if (num == i) {
                            Pattern p1 = Pattern.compile(">([^<>]*)<");
                            Matcher m1 = p1.matcher(matcher.group(0).trim());
                            if (m1.find()) {
                                String value = m1.group(1).trim().equals("") ? null
                                        : m1.group(1).trim();
                                Class<?> beanType = field.getType();
                                String setMethodName = "set"
                                        + fieldname.substring(0, 1)
                                        .toUpperCase()
                                        + fieldname.substring(1);
                                Method m = obj1.getClass().getMethod(
                                        setMethodName, beanType);
                                m.invoke(obj1, value);
                            }
                        }
                        num++;
                    }
                } catch (NullPointerException e) {
                    continue;
                }
            }
            objs2[i] = (BaseObject) obj1;
        }
        return objs2;
    }

    /**
     * 基础的Object对象，实现Cloneable接口，用于调用clone()
     */
    class BaseObject implements Cloneable {
        @Override
        public Object clone() {
            Object obj = null;
            try {
                obj = super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return obj;
        }
    }

    /**
     * xml中需要的信息封装到User
     * 这里继承BaseObject用于第二个解析xml的方法
     * 注意：User的属性名必须与xml字符串中的标签一致
     */
    class User extends BaseObject {
        String users_id;//用户ID
        String users_name;//用户名
        String users_group;//用户分组
        String users_address;//用户地址

        public String getUsers_id() {
            return users_id;
        }

        public void setUsers_id(String users_id) {
            this.users_id = users_id;
        }

        public String getUsers_name() {
            return users_name;
        }

        public void setUsers_name(String users_name) {
            this.users_name = users_name;
        }

        public String getUsers_group() {
            return users_group;
        }

        public void setUsers_group(String users_group) {
            this.users_group = users_group;
        }

        public String getUsers_address() {
            return users_address;
        }

        public void setUsers_address(String users_address) {
            this.users_address = users_address;
        }

        @Override
        public String toString() {
            return "User{" +
                    "users_id=" + users_id +
                    ", users_name='" + users_name + '\'' +
                    ", users_group=" + users_group +
                    ", users_address='" + users_address + '\'' +
                    '}';
        }

    }

}
